home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / puma.lha / puma / src / C.mi < prev    next >
Text File  |  1992-09-25  |  46KB  |  1,849 lines

  1. IMPLEMENTATION MODULE C;
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15. IMPORT SYSTEM, System, IO, Tree;
  16. (* line 7 "" *)
  17.  
  18.  
  19. FROM Positions    IMPORT tPosition;
  20. FROM IO        IMPORT StdOutput, WriteS, WriteNl;
  21. FROM Strings    IMPORT tString, IntToString, Concatenate, ArrayToString;
  22. FROM StringMem    IMPORT WriteString;
  23. FROM Idents    IMPORT tIdent, NoIdent, MakeIdent;
  24. FROM Texts    IMPORT WriteText;
  25. FROM Sets    IMPORT IsElement, IsNotEqual, Minimum, Maximum, IsEmpty;
  26. FROM Semantics    IMPORT IdentifyVar, UserTypes, LookupClass;
  27. FROM Optimize    IMPORT NeedsTempo, NeedsMatch, NeedsNoFinale, GetRule;
  28. FROM Tree    IMPORT NoTree, tTree, Options, f, SourceFile, WI, WN;
  29.  
  30. VAR
  31.    RoutineKind    : (kProcedure, kFunction, kPredicate);
  32.    WithCount    ,
  33.    RuleCount    ,
  34.    ListCount    : INTEGER;
  35.    i, j        : CARDINAL;
  36.    rule        ,
  37.    TheClass    ,
  38.    InFormals    ,
  39.    OutFormals    ,
  40.    ReturnFormals,
  41.    Decls    : tTree;
  42.    TheName    : tIdent;
  43.    TemposDone    : BOOLEAN;
  44.  
  45. PROCEDURE WriteLine (Line: tPosition);
  46.    BEGIN
  47.       IF Line.Line # 0 THEN
  48.      IF IsElement (ORD ('6'), Options) THEN
  49.         WriteS (f, "# line "); WN (Line.Line); WriteS (f, ' "'); WriteS (f, SourceFile); WriteS (f, '"'); WriteNl (f);
  50.      ELSE
  51.         WriteS (f, "/* line "); WN (Line.Line); WriteS (f, ' "'); WriteS (f, SourceFile); WriteS (f, '" */'); WriteNl (f);
  52.      END;
  53.       END;
  54.    END WriteLine;
  55.  
  56. PROCEDURE Match (t, Formals: tTree);
  57.    VAR TreeName    : tIdent;
  58.    VAR Pattern    : tTree;
  59.    BEGIN
  60.       IF (t^.Kind = Tree.NoPattern) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  61.       Pattern := t^.OnePattern.Pattern;
  62.       CASE Pattern^.Kind OF
  63.       | Tree.Decompose: WITH Pattern^.Decompose DO
  64.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  65.         IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) OR
  66.            IsNotEqual (Object^.Class.TypeDesc^.NodeTypes.Types, Formals^.Formal.TypeDesc^.NodeTypes.Types) THEN
  67.            IF Object^.Class.Extensions^.Kind = Tree.NoClass THEN    (* Low ? *)
  68.           WriteS (f, '   if ('); ImplC (Path); WriteS (f, '->Kind != k'); WI (Object^.Class.Name);
  69.            ELSE
  70.           WriteS (f, '   if (! '); WI (TreeName); WriteS (f, '_IsType ('); ImplC (Path); WriteS (f, ', k'); WI (Object^.Class.Name); WriteS (f, ')'); 
  71.            END;
  72.            WriteS (f, ") goto yyL"); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  73.         END;
  74.         Match (Patterns, Object^.Class.Formals);
  75.      END;
  76.  
  77.       | Tree.VarDef: WITH Pattern^.VarDef DO
  78.         IF Object # NoTree THEN
  79.            WITH Object^.Formal DO
  80.           WriteS (f, '   if (! (equal'); DefC (TypeDesc); WriteS (f, ' ('); ImplC (Path);
  81.           WriteS (f, ", "); ImplC (Pattern^.VarDef.Path); WriteS (f, "))) goto yyL"); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  82.            END;
  83.         END;
  84.      END;
  85.  
  86.       | Tree.NilTest:
  87.      WriteS (f, "   if ("); ImplC (Pattern^.NilTest.Path); WriteS (f, ' != NULL) goto yyL'); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  88.  
  89.       | Tree.DontCare1:
  90.       | Tree.DontCare: RETURN;
  91.  
  92.       | Tree.Value: WITH Pattern^.Value DO
  93.         AssignTempo (Expr);
  94.         IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) AND
  95.            IsElement (Formals^.Formal.TypeDesc^.UserType.Type, UserTypes) THEN
  96.            WriteS (f, "  {"); DefC (Formals^.Formal.TypeDesc); WriteS (f, " yyT; yyT = "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  97.            WriteS (f, '   if (! (equal'); DefC (Formals^.Formal.TypeDesc);
  98.            WriteS (f, " ("); ImplC (Path); WriteS (f, ", yyT))) goto yyL"); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  99.            WriteS (f, "  }"); WriteNl (f);
  100.         ELSE
  101.            WriteS (f, '   if (! (equal'); DefC (Formals^.Formal.TypeDesc);
  102.            WriteS (f, " ("); ImplC (Path); WriteS (f, ", "); Expression (Expr); WriteS (f, "))) goto yyL"); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  103.         END;
  104.         MatchExpr (Expr);
  105.      END;
  106.       END;
  107.       Match (t^.OnePattern.Next, Formals^.Formal.Next);
  108.    END Match;
  109.  
  110. PROCEDURE MatchExprs (t: tTree);
  111.    BEGIN
  112.       IF t^.Kind = Tree.NoExpr THEN RETURN; END;
  113.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
  114.       MatchExpr (t^.OneExpr.Expr);
  115.       MatchExprs (t^.OneExpr.Next);
  116.    END MatchExprs;
  117.  
  118. PROCEDURE MatchExpr (t: tTree);
  119.    BEGIN
  120.       CASE t^.Kind OF
  121.       | Tree.Compose:
  122.      MatchExprs (t^.Compose.Exprs);
  123.  
  124.       | Tree.VarUse    :
  125.       | Tree.Nil    :
  126.       | Tree.DontCare1    :
  127.       | Tree.TargetExpr    :
  128.       | Tree.StringExpr    :
  129.       | Tree.AttrDesc    :
  130.  
  131.       | Tree.Call    : WITH t^.Call DO
  132.         MatchExpr (Expr);
  133.         MatchExprs (Exprs);
  134.         IF Object # NoTree THEN
  135.            Match (Patterns, Object^.Routine.OutForm);
  136.         END;
  137.      END;
  138.  
  139.       | Tree.Binary    : WITH t^.Binary DO
  140.         MatchExpr (Lop);
  141.         MatchExpr (Rop);
  142.      END;
  143.  
  144.       | Tree.PreOperator, Tree.PostOperator    :
  145.      MatchExpr (t^.PreOperator.Expr);
  146.  
  147.       | Tree.Index    :
  148.      MatchExpr (t^.Index.Expr);
  149.      MatchExprs (t^.Index.Exprs);
  150.  
  151.       | Tree.Parents    :
  152.      MatchExpr (t^.Parents.Expr);
  153.       END;
  154.    END MatchExpr;
  155.  
  156. PROCEDURE AssignTempos (t: tTree);
  157.    BEGIN
  158.       IF t^.Kind = Tree.NoExpr THEN RETURN; END;
  159.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
  160.       AssignTempo (t^.OneExpr.Expr);
  161.       AssignTempos (t^.OneExpr.Next);
  162.    END AssignTempos;
  163.  
  164. PROCEDURE AssignTempo (t: tTree);
  165.    VAR TreeName    : tIdent;
  166.    BEGIN
  167.       CASE t^.Kind OF
  168.       | Tree.Compose: WITH t^.Compose DO
  169.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  170.         WriteS (f, "   yyALLOC (t"); WI (TreeName); WriteS (f, ","); WI (TreeName); WriteS (f, "_PoolFreePtr,"); 
  171.         WI (TreeName); WriteS (f, "_PoolMaxPtr,"); WI (TreeName); WriteS (f, "_Alloc,"); WI (TreeName);
  172.         WriteS (f, "_NodeSize,Make"); WI (TreeName); WriteS (f, ","); WI (Tempo); WriteS (f, ",k"); WI (Object^.Class.Name); WriteS (f, ")"); WriteNl (f);
  173.         AssignSubFormals (Exprs, Object^.Class.Formals, Tempo, Object^.Class.Name);
  174.      END;
  175.  
  176.       | Tree.VarUse    :
  177.       | Tree.Nil    :
  178.       | Tree.DontCare1    :
  179.       | Tree.TargetExpr    :
  180.       | Tree.StringExpr    :
  181.       | Tree.AttrDesc    :
  182.  
  183.       | Tree.Call    : WITH t^.Call DO
  184.         AssignTempo (Expr);
  185.         AssignTempos (Exprs);
  186.      END;
  187.  
  188.       | Tree.Binary    : WITH t^.Binary DO
  189.         AssignTempo (Lop);
  190.         AssignTempo (Rop);
  191.      END;
  192.  
  193.       | Tree.PreOperator, Tree.PostOperator    :
  194.      AssignTempo (t^.PreOperator.Expr);
  195.  
  196.       | Tree.Index    :
  197.      AssignTempo (t^.Index.Expr);
  198.      AssignTempos (t^.Index.Exprs);
  199.  
  200.       | Tree.Parents    :
  201.      AssignTempo (t^.Parents.Expr);
  202.       END;
  203.    END AssignTempo;
  204.  
  205. PROCEDURE AssignFormals (t, Formals: tTree);
  206.    BEGIN
  207.       IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  208.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
  209.      BeginFormals (Formals);
  210.      RETURN;
  211.       END;
  212.       AssignFormal (t^.OneExpr.Expr, Formals);
  213.       MatchExpr (t^.OneExpr.Expr);
  214.       AssignFormals (t^.OneExpr.Next, Formals^.Formal.Next);
  215.    END AssignFormals;
  216.  
  217. PROCEDURE AssignFormal (t, Formals: tTree);
  218.    VAR TreeName, With    : tIdent;
  219.    BEGIN
  220.       IF t^.Kind = Tree.Compose THEN
  221.      WITH t^.Compose DO
  222.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  223.         With := MakeWith ();
  224.         WriteS (f, "   {register t"); WI (TreeName); WriteS (f, " "); WI (With); WriteS (f, ";"); WriteNl (f);
  225.         WriteS (f, "    yyALLOC (t"); WI (TreeName); WriteS (f, ","); WI (TreeName); WriteS (f, "_PoolFreePtr,"); 
  226.         WI (TreeName); WriteS (f, "_PoolMaxPtr,"); WI (TreeName); WriteS (f, "_Alloc,"); WI (TreeName);
  227.         WriteS (f, "_NodeSize,Make"); WI (TreeName); WriteS (f, ","); WI (With); WriteS (f, ",k"); WI (Object^.Class.Name); WriteS (f, ")"); WriteNl (f);
  228.         WriteS (f, "    * "); WI (Formals^.Formal.Name); WriteS (f, " = "); WI (With); WriteS (f, ";"); WriteNl (f);
  229.         AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
  230.         WriteS (f, "   }"); WriteNl (f);
  231.      END;
  232.       ELSE
  233.      AssignTempo (t);
  234.       END;
  235.  
  236.       CASE t^.Kind OF
  237.       | Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
  238.     Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
  239.     Tree.AttrDesc:
  240.      WriteS (f, "   * "); WI (Formals^.Formal.Name); WriteS (f, " = "); Expression (t); WriteS (f, ";"); WriteNl (f);
  241.       | Tree.DontCare1:
  242.      WriteS (f, "    begin"); DefC (Formals^.Formal.TypeDesc); WriteS (f, " (* "); WI (Formals^.Formal.Name); WriteS (f, ")"); WriteNl (f);
  243.       ELSE
  244.       END;
  245.    END AssignFormal;
  246.  
  247. PROCEDURE AssignSubFormals (t, Formals: tTree; PrevWith, Composer: tIdent);
  248.    BEGIN
  249.       IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
  250.       IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
  251.      BeginSubFormals (Formals, PrevWith, Composer);
  252.      RETURN;
  253.       END;
  254.       AssignSubFormal (t^.OneExpr.Expr, Formals, PrevWith, Composer);
  255.       AssignSubFormals (t^.OneExpr.Next, Formals^.Formal.Next, PrevWith, Composer);
  256.    END AssignSubFormals;
  257.  
  258. PROCEDURE AssignSubFormal (t, Formals: tTree; PrevWith, Composer: tIdent);
  259.    VAR TreeName, With    : tIdent;
  260.    BEGIN
  261.       IF t^.Kind = Tree.Compose THEN
  262.      WITH t^.Compose DO
  263.         TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
  264.         With := MakeWith ();
  265.         WriteS (f, "   {register t"); WI (TreeName); WriteS (f, " "); WI (With); WriteS (f, ";"); WriteNl (f);
  266.         WriteS (f, "    yyALLOC (t"); WI (TreeName); WriteS (f, ","); WI (TreeName); WriteS (f, "_PoolFreePtr,"); 
  267.         WI (TreeName); WriteS (f, "_PoolMaxPtr,"); WI (TreeName); WriteS (f, "_Alloc,"); WI (TreeName);
  268.         WriteS (f, "_NodeSize,Make"); WI (TreeName); WriteS (f, ","); WI (With); WriteS (f, ",k"); WI (Object^.Class.Name); WriteS (f, ")"); WriteNl (f);
  269.         WriteS (f, "    "); WI (PrevWith); WriteS (f, "->"); WI (Composer); WriteS (f, "."); WI (Formals^.Formal.Name); WriteS (f, " = "); WI (With); WriteS (f, ";"); WriteNl (f);
  270.         AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
  271.         WriteS (f, "   }"); WriteNl (f);
  272.      END;
  273.       ELSE
  274.      AssignTempo (t);
  275.       END;
  276.  
  277.       CASE t^.Kind OF
  278.       | Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
  279.     Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
  280.     Tree.AttrDesc:
  281.      WriteS (f, "    "); WI (PrevWith); WriteS (f, "->"); WI (Composer); WriteS (f, "."); WI (Formals^.Formal.Name); WriteS (f, " = "); Expression (t); WriteS (f, ";"); WriteNl (f);
  282.       | Tree.DontCare1:
  283.      WriteS (f, "    begin"); DefC (Formals^.Formal.TypeDesc); WriteS (f, " ("); WI (PrevWith); WriteS (f, "->"); WI (Composer); WriteS (f, "."); WI (Formals^.Formal.Name); WriteS (f, ")"); WriteNl (f);
  284.       ELSE
  285.       END;
  286.    END AssignSubFormal;
  287.  
  288. PROCEDURE BeginFormals (Formals: tTree);
  289.    BEGIN
  290.       IF Formals^.Kind = Tree.Formal THEN
  291.      WITH Formals^.Formal DO
  292.         WriteS (f, "    begin"); DefC (TypeDesc); WriteS (f, " (* "); WI (Name); WriteS (f, ")"); WriteNl (f);
  293.         BeginFormals (Next);
  294.      END;
  295.       END;
  296.    END BeginFormals;
  297.  
  298. PROCEDURE BeginSubFormals (Formals: tTree; PrevWith, Composer: tIdent);
  299.    BEGIN
  300.       IF Formals^.Kind = Tree.Formal THEN
  301.      WITH Formals^.Formal DO
  302.         WriteS (f, "    begin"); DefC (TypeDesc); WriteS (f, " ("); WI (PrevWith); WriteS (f, "->"); WI (Composer); WriteS (f, "."); WI (Name); WriteS (f, ")"); WriteNl (f);
  303.         BeginSubFormals (Next, PrevWith, Composer);
  304.      END;
  305.       END;
  306.    END BeginSubFormals;
  307.  
  308. PROCEDURE ConsPatterns (t: tTree; ListCount: INTEGER): INTEGER;
  309.    BEGIN
  310.       IF t^.Kind = Tree.NoPattern THEN RETURN ListCount; END;
  311.       WITH t^.OnePattern DO
  312.      IF Pattern^.Kind = Tree.DontCare THEN
  313.         RETURN ConsTempos (Pattern^.DontCare.Tempos, ListCount, TRUE);
  314.      ELSE
  315.         IF ListCount > 0 THEN WriteS (f, ", "); END;
  316.         WriteS (f, "& "); WI (Pattern^.Pattern.Tempo);
  317.         RETURN ConsPatterns (Next, ListCount + 1);
  318.      END;
  319.       END;
  320.    END ConsPatterns;
  321.  
  322. PROCEDURE ConsTempos (t: tTree; ListCount: INTEGER; IsRef: BOOLEAN): INTEGER;
  323.    BEGIN
  324.       IF t^.Kind = Tree.Formal THEN
  325.      IF ListCount > 0 THEN WriteS (f, ", "); END;
  326.      IF IsRef THEN WriteS (f, "& "); END;
  327.      WI (t^.Formal.Name);
  328.      RETURN ConsTempos (t^.Formal.Next, ListCount + 1, IsRef);
  329.       ELSE
  330.      RETURN ListCount;
  331.       END;
  332.    END ConsTempos;
  333.  
  334. PROCEDURE Expressions (t: tTree; ListCount: INTEGER): INTEGER;
  335.    BEGIN
  336.       IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
  337.       WITH t^.OneExpr DO
  338.      IF Expr^.Kind = Tree.DontCare THEN
  339.         RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
  340.      ELSE
  341.         IF ListCount > 0 THEN WriteS (f, ", "); END;
  342.         Expression (Expr);
  343.         RETURN Expressions (Next, ListCount + 1);
  344.      END;
  345.       END;
  346.    END Expressions;
  347.  
  348. PROCEDURE Expressions2 (t: tTree; ListCount: INTEGER; Formals: tTree): INTEGER;
  349.    BEGIN
  350.       IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
  351.       WITH t^.OneExpr DO
  352.      IF Expr^.Kind = Tree.DontCare THEN
  353.         RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
  354.      ELSE
  355.         IF ListCount > 0 THEN WriteS (f, ", "); END;
  356.         IF Formals^.Formal.Path^.Var.IsOutput THEN WriteS (f, "& "); END;
  357.         Expression (Expr);
  358.         RETURN Expressions2 (Next, ListCount + 1, Formals^.Formal.Next);
  359.      END;
  360.       END;
  361.    END Expressions2;
  362.  
  363. PROCEDURE Expression (t: tTree);
  364.    BEGIN
  365.       CASE t^.Kind OF
  366.       | Tree.Compose    : WI (t^.Compose.Tempo);
  367.  
  368.       | Tree.Nil    : WriteS (f, "NULL"); 
  369.  
  370.       | Tree.VarUse    : WITH t^.VarUse DO
  371.         IF Object # NoTree THEN
  372.            ImplC (Object^.Formal.Path);
  373.         ELSE
  374.            WI (Name);
  375.         END;
  376.      END;
  377.  
  378.       | Tree.DontCare1    : WI (t^.DontCare1.Tempo);
  379.  
  380.       | Tree.Call    : WITH t^.Call DO
  381.         Expression (Expr); WriteS (f, " ("); 
  382.         IF Object # NoTree THEN
  383.            ListCount := Expressions2 (Exprs, 0, Object^.Routine.InForm);
  384.            ListCount := ConsPatterns (Patterns, ListCount);
  385.         ELSE
  386.            ListCount := Expressions (Exprs, 0);
  387.            ListCount := Expressions (Patterns, ListCount);
  388.         END;
  389.         WriteS (f, ")"); 
  390.      END;
  391.  
  392.       | Tree.Binary    : WITH t^.Binary DO
  393.         Expression (Lop); WriteS (f, " "); WI (Operator); WriteS (f, " "); Expression (Rop);
  394.      END;
  395.  
  396.       | Tree.PreOperator    :
  397.      WI (t^.PreOperator.Operator); WriteS (f, " "); Expression (t^.PreOperator.Expr);
  398.  
  399.       | Tree.PostOperator    :
  400.      Expression (t^.PostOperator.Expr); WriteS (f, " "); WI (t^.PostOperator.Operator);
  401.  
  402.       | Tree.Index    :
  403.      Expression (t^.Index.Expr); WriteS (f, " ["); ListCount := Expressions (t^.Index.Exprs, 0); WriteS (f, "]"); 
  404.  
  405.       | Tree.Parents    : WriteS (f, "("); Expression (t^.Parents.Expr); WriteS (f, ")"); 
  406.  
  407.       | Tree.TargetExpr    : ImplC (t^.TargetExpr.Expr);
  408.  
  409.       | Tree.StringExpr    : WriteString (f, t^.StringExpr.String);
  410.  
  411.       | Tree.AttrDesc    : WITH t^.AttrDesc DO
  412.         ImplC (Object^.Formal.Path); WriteS (f, "->"); WI (Type); WriteS (f, "."); WI (Attribute);
  413.      END;
  414.       END;
  415.    END Expression;
  416.  
  417. PROCEDURE MakeWith (): tIdent;
  418.    VAR String1, String2    : tString;
  419.    BEGIN
  420.       INC (WithCount);
  421.       ArrayToString ("yyW", String1);
  422.       IntToString (WithCount, String2);
  423.       Concatenate (String1, String2);
  424.       RETURN MakeIdent (String1);
  425.    END MakeWith;
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484. PROCEDURE yyAbort (yyFunction: ARRAY OF CHAR);
  485.  BEGIN
  486.   IO.WriteS (IO.StdError, 'Error: module C, routine ');
  487.   IO.WriteS (IO.StdError, yyFunction);
  488.   IO.WriteS (IO.StdError, ' failed');
  489.   IO.WriteNl (IO.StdError);
  490.   Exit;
  491.  END yyAbort;
  492.  
  493. PROCEDURE yyIsEqual (yya, yyb: ARRAY OF SYSTEM.BYTE): BOOLEAN;
  494.  VAR yyi    : INTEGER;
  495.  BEGIN
  496.   FOR yyi := 0 TO INTEGER (HIGH (yya)) DO
  497.    IF yya [yyi] # yyb [yyi] THEN RETURN FALSE; END;
  498.   END;
  499.   RETURN TRUE;
  500.  END yyIsEqual;
  501.  
  502. PROCEDURE MacroC (t: Tree.tTree);
  503.  VAR yyTempo: RECORD CASE : INTEGER OF
  504.  END; END;
  505.  BEGIN
  506.   IF t = Tree.NoTree THEN RETURN; END;
  507.   IF (t^.Kind = Tree.Spec) THEN
  508. (* line 420 "" *)
  509.      WITH t^.Spec DO
  510. (* line 420 "" *)
  511.       
  512.     MacroC (TreeNames);
  513. ;
  514.       RETURN;
  515.      END;
  516.  
  517.   END;
  518.   IF (t^.Kind = Tree.TreeName) THEN
  519. (* line 423 "" *)
  520.      WITH t^.TreeName DO
  521. (* line 423 "" *)
  522.       
  523.     WriteS (f, "# define begint"); WI (Name); WriteS (f, "(a)    a = NULL;"); WriteNl (f);
  524.     WriteS (f, "# define equalt"); WI (Name); WriteS (f, "(a, b)    IsEqual"); WI (Name); WriteS (f, " (a, b)"); WriteNl (f);
  525.     MacroC (Next);
  526. ;
  527.       RETURN;
  528.      END;
  529.  
  530.   END;
  531.  END MacroC;
  532.  
  533. PROCEDURE DefC (t: Tree.tTree);
  534.  VAR yyTempo: RECORD CASE : INTEGER OF
  535.  END; END;
  536.  BEGIN
  537.   IF t = Tree.NoTree THEN RETURN; END;
  538.   IF (t^.Kind = Tree.Spec) THEN
  539. (* line 432 "" *)
  540.      WITH t^.Spec DO
  541. (* line 432 "" *)
  542.       
  543.     WriteS (f, "# ifndef yy"); WI (TrafoName); WriteNl (f);
  544.     WriteS (f, "# define yy"); WI (TrafoName); WriteNl (f);
  545.     WriteNl (f);
  546.     WriteS (f, "# if defined __STDC__ | defined __cplusplus"); WriteNl (f);
  547.     WriteS (f, "# define ARGS(parameters)    parameters"); WriteNl (f);
  548.     WriteS (f, "# else"); WriteNl (f);
  549.     WriteS (f, "# define ARGS(parameters)    ()"); WriteNl (f);
  550.     WriteS (f, "# endif"); WriteNl (f);
  551.     WriteNl (f);
  552.     WriteS (f, "# ifndef bool"); WriteNl (f);
  553.     WriteS (f, "# define bool char"); WriteNl (f);
  554.     WriteS (f, "# endif"); WriteNl (f);
  555.     WriteNl (f);
  556.     DefC (TreeNames);
  557.     WriteNl (f);
  558.     WriteLine (Codes^.Codes.ImportLine);
  559.     WriteText (f, Codes^.Codes.Import);
  560.     WriteLine (Codes^.Codes.ExportLine);
  561.     WriteText (f, Codes^.Codes.Export);
  562.     WriteNl (f);
  563.     WriteS (f, "extern void (* "); WI (TrafoName); WriteS (f, "_Exit) ();"); WriteNl (f);
  564.     WriteNl (f);
  565.     DefC (Public);
  566.     WriteNl (f);
  567.     WriteS (f, "extern void Begin"); WI (TrafoName); WriteS (f, " ();"); WriteNl (f);
  568.     WriteS (f, "extern void Close"); WI (TrafoName); WriteS (f, " ();"); WriteNl (f);
  569.     WriteNl (f);
  570.     WriteS (f, "# endif"); WriteNl (f);
  571. ;
  572.       RETURN;
  573.      END;
  574.  
  575.   END;
  576.   IF (t^.Kind = Tree.TreeName) THEN
  577. (* line 462 "" *)
  578.      WITH t^.TreeName DO
  579. (* line 462 "" *)
  580.       
  581.     WriteS (f, '# include "'); WI (Name); WriteS (f, '.h"'); WriteNl (f);
  582.     DefC (Next);
  583. ;
  584.       RETURN;
  585.      END;
  586.  
  587.   END;
  588.   IF (t^.Kind = Tree.Name) THEN
  589. (* line 466 "" *)
  590.      WITH t^.Name DO
  591. (* line 466 "" *)
  592.       
  593.     IF Object # NoTree THEN
  594.        ListCount := 0;
  595.        WriteS (f, "extern "); 
  596.        IF Object^.Kind = Tree.Procedure THEN
  597.           WriteS (f, "void"); 
  598.        ELSIF Object^.Kind = Tree.Function THEN
  599.           DefC (Object^.Function.ReturnForm^.Formal.TypeDesc);
  600.        ELSIF Object^.Kind = Tree.Predicate THEN
  601.           WriteS (f, "bool"); 
  602.        END;
  603.        WriteS (f, " "); WI (Name); WriteS (f, " ARGS(("); 
  604.        DefC (Object^.Routine.InForm);
  605.        DefC (Object^.Routine.OutForm);
  606.        WriteS (f, "));"); WriteNl (f);
  607.     END;
  608.     DefC (Next);
  609. ;
  610.       RETURN;
  611.      END;
  612.  
  613.   END;
  614.   IF (t^.Kind = Tree.Formal) THEN
  615. (* line 484 "" *)
  616.      WITH t^.Formal DO
  617. (* line 484 "" *)
  618.       
  619.     IF ListCount > 0 THEN WriteS (f, ", "); END;
  620.     DefC (TypeDesc);
  621.     IF Path^.Var.IsOutput THEN WriteS (f, " *"); END;
  622.     WriteS (f, " "); WI (Name);
  623.     INC (ListCount);
  624.     DefC (Next);
  625. ;
  626.       RETURN;
  627.      END;
  628.  
  629.   END;
  630.   IF (t^.Kind = Tree.NodeTypes) THEN
  631. (* line 492 "" *)
  632.      WITH t^.NodeTypes DO
  633. (* line 492 "" *)
  634.       
  635.     WriteS (f, "t"); WI (TreeName^.TreeName.Name);
  636. ;
  637.       RETURN;
  638.      END;
  639.  
  640.   END;
  641.   IF (t^.Kind = Tree.UserType) THEN
  642. (* line 495 "" *)
  643.      WITH t^.UserType DO
  644. (* line 495 "" *)
  645.       
  646.     WI (Type);
  647. ;
  648.       RETURN;
  649.      END;
  650.  
  651.   END;
  652.  END DefC;
  653.  
  654. PROCEDURE Forward (t: Tree.tTree);
  655.  VAR yyTempo: RECORD CASE : INTEGER OF
  656.  END; END;
  657.  BEGIN
  658.   IF t = Tree.NoTree THEN RETURN; END;
  659.   IF (t^.Kind = Tree.Procedure) THEN
  660. (* line 502 "" *)
  661.      WITH t^.Procedure DO
  662. (* line 502 "" *)
  663.       
  664.     ListCount := 0;
  665.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  666.     WriteS (f, "void "); WI (Name); WriteS (f, " ARGS(("); 
  667.     DefC (InForm);
  668.     DefC (OutForm);
  669.     WriteS (f, "));"); WriteNl (f);
  670.     Forward (Next);
  671. ;
  672.       RETURN;
  673.      END;
  674.  
  675.   END;
  676.   IF (t^.Kind = Tree.Function) THEN
  677. (* line 511 "" *)
  678.      WITH t^.Function DO
  679. (* line 511 "" *)
  680.       
  681.     ListCount := 0;
  682.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  683.     DefC (ReturnForm^.Formal.TypeDesc); WriteS (f, " "); WI (Name); WriteS (f, " ARGS(("); 
  684.     DefC (InForm);
  685.     DefC (OutForm);
  686.     WriteS (f, "));"); WriteNl (f);
  687.     Forward (Next);
  688. ;
  689.       RETURN;
  690.      END;
  691.  
  692.   END;
  693.   IF (t^.Kind = Tree.Predicate) THEN
  694. (* line 520 "" *)
  695.      WITH t^.Predicate DO
  696. (* line 520 "" *)
  697.       
  698.     ListCount := 0;
  699.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  700.     WriteS (f, "bool "); WI (Name); WriteS (f, " ARGS(("); 
  701.     DefC (InForm);
  702.     DefC (OutForm);
  703.     WriteS (f, "));"); WriteNl (f);
  704.     Forward (Next);
  705. ;
  706.       RETURN;
  707.      END;
  708.  
  709.   END;
  710.  END Forward;
  711.  
  712. PROCEDURE ProcHead1 (t: Tree.tTree);
  713.  VAR yyTempo: RECORD CASE : INTEGER OF
  714.  END; END;
  715.  BEGIN
  716.   IF t = Tree.NoTree THEN RETURN; END;
  717.   IF (t^.Kind = Tree.Formal) THEN
  718. (* line 533 "" *)
  719.      WITH t^.Formal DO
  720. (* line 533 "" *)
  721.       
  722.     IF ListCount > 0 THEN WriteS (f, ", "); END;
  723.     WI (Name);
  724.     INC (ListCount);
  725.     ProcHead1 (Next);
  726. ;
  727.       RETURN;
  728.      END;
  729.  
  730.   END;
  731.  END ProcHead1;
  732.  
  733. PROCEDURE ProcHead2 (t: Tree.tTree);
  734.  VAR yyTempo: RECORD CASE : INTEGER OF
  735.  END; END;
  736.  BEGIN
  737.   IF t = Tree.NoTree THEN RETURN; END;
  738.   IF (t^.Kind = Tree.Formal) THEN
  739. (* line 543 "" *)
  740.      WITH t^.Formal DO
  741. (* line 543 "" *)
  742.       
  743.     WriteS (f, " "); 
  744.     IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN WriteS (f, "register "); END;
  745.     ImplC (TypeDesc); IF Path^.Var.IsOutput THEN WriteS (f, " *"); END; WriteS (f, " "); WI (Name); WriteS (f, ";"); WriteNl (f);
  746.     ProcHead2 (Next);
  747. ;
  748.       RETURN;
  749.      END;
  750.  
  751.   END;
  752.  END ProcHead2;
  753.  
  754. PROCEDURE ProcHead3 (t: Tree.tTree);
  755.  VAR yyTempo: RECORD CASE : INTEGER OF
  756.  END; END;
  757.  BEGIN
  758.   IF t = Tree.NoTree THEN RETURN; END;
  759.   IF (t^.Kind = Tree.Formal) THEN
  760. (* line 553 "" *)
  761.      WITH t^.Formal DO
  762. (* line 553 "" *)
  763.       
  764.     IF ListCount > 0 THEN WriteS (f, ", "); END;
  765.     IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN WriteS (f, "register "); END;
  766.     ImplC (TypeDesc); IF Path^.Var.IsOutput THEN WriteS (f, " *"); END; WriteS (f, " "); WI (Name);
  767.     INC (ListCount);
  768.     ProcHead3 (Next);
  769. ;
  770.       RETURN;
  771.      END;
  772.  
  773.   END;
  774.  END ProcHead3;
  775.  
  776. PROCEDURE ImplC (t: Tree.tTree);
  777.  VAR yyTempo: RECORD CASE : INTEGER OF
  778.  | 14: yyR14: RECORD
  779.   Var: tTree;
  780.   END;
  781.  END; END;
  782.  BEGIN
  783.   IF t = Tree.NoTree THEN RETURN; END;
  784.  
  785.   CASE t^.Kind OF
  786.   | Tree.Spec:
  787. (* line 564 "" *)
  788.      WITH t^.Spec DO
  789. (* line 564 "" *)
  790.       
  791.     WriteS (f, '# include "'); WI (TrafoName); WriteS (f, '.h"'); WriteNl (f);
  792.     WriteS (f, "# ifdef __cplusplus"); WriteNl (f);
  793.     WriteS (f, 'extern "C" {'); WriteNl (f);
  794.     WriteS (f, '# include "System.h"'); WriteNl (f);
  795.     WriteS (f, "}"); WriteNl (f);
  796.     WriteS (f, "# else"); WriteNl (f);
  797.     WriteS (f, '# include "System.h"'); WriteNl (f);
  798.     WriteS (f, "# endif"); WriteNl (f);
  799.     WriteS (f, "# include <stdio.h>"); WriteNl (f);
  800.     DefC (TreeNames);
  801.     WriteNl (f);
  802.       IF NOT IsElement (ORD ('m'), Options) THEN
  803.     WriteS (f, "# define yyInline"); WriteNl (f);
  804.       END;
  805.     WriteS (f, "# ifndef NULL"); WriteNl (f);
  806.     WriteS (f, "# define NULL 0L"); WriteNl (f);
  807.     WriteS (f, "# endif"); WriteNl (f);
  808.     WriteS (f, "# ifndef false"); WriteNl (f);
  809.     WriteS (f, "# define false 0"); WriteNl (f);
  810.     WriteS (f, "# endif"); WriteNl (f);
  811.     WriteS (f, "# ifndef true"); WriteNl (f);
  812.     WriteS (f, "# define true 1"); WriteNl (f);
  813.     WriteS (f, "# endif"); WriteNl (f);
  814.     WriteNl (f);
  815.     WriteS (f, "# ifdef yyInline"); WriteNl (f);
  816.     WriteS (f, "# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) \"); WriteNl (f);
  817.     WriteS (f, "  if ((ptr = (tree) free) >= (tree) max) ptr = alloc (); \"); WriteNl (f);
  818.     WriteS (f, "  free += nodesize [kind]; \"); WriteNl (f);
  819.     WriteS (f, "  ptr->yyHead.yyMark = 0; \"); WriteNl (f);
  820.     WriteS (f, "  ptr->Kind = kind;"); WriteNl (f);
  821.     WriteS (f, "# else"); WriteNl (f);
  822.     WriteS (f, "# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) ptr = make (kind);"); WriteNl (f);
  823.     WriteS (f, "# endif"); WriteNl (f);
  824.     WriteNl (f);
  825.     WriteS (f, "# define yyWrite(s) (void) fputs (s, yyf)"); WriteNl (f);
  826.     WriteS (f, "# define yyWriteNl (void) fputc ('\n', yyf)"); WriteNl (f);
  827.     WriteNl (f);
  828.     WriteLine (Codes^.Codes.GlobalLine);
  829.     WriteText (f, Codes^.Codes.Global);
  830.     WriteS (f, '# include "yy'); WI (TrafoName); WriteS (f, '.w"'); WriteNl (f);
  831.     WriteNl (f);
  832.     WriteS (f, "static void yyExit () { Exit (1); }"); WriteNl (f);
  833.     WriteNl (f);
  834.     WriteS (f, "void (* "); WI (TrafoName); WriteS (f, "_Exit) () = yyExit;"); WriteNl (f);
  835.     WriteNl (f);
  836.     WriteS (f, "static FILE * yyf = stdout;"); WriteNl (f);
  837.     WriteNl (f);
  838.     WriteS (f, "static void yyAbort"); WriteNl (f);
  839.     WriteS (f, "# ifdef __cplusplus"); WriteNl (f);
  840.     WriteS (f, " (char * yyFunction)"); WriteNl (f);
  841.     WriteS (f, "# else"); WriteNl (f);
  842.     WriteS (f, " (yyFunction) char * yyFunction;"); WriteNl (f);
  843.     WriteS (f, "# endif"); WriteNl (f);
  844.     WriteS (f, "{"); WriteNl (f);
  845.     WriteS (f, ' (void) fprintf (stderr, "Error: module '); WI (TrafoName); WriteS (f, ', routine %s failed\n", yyFunction);'); WriteNl (f);
  846.     WriteS (f, " "); WI (TrafoName); WriteS (f, "_Exit ();"); WriteNl (f);
  847.     WriteS (f, "}"); WriteNl (f);
  848.     WriteNl (f);
  849.     Forward (Routines);
  850.     WriteNl (f);
  851.     ImplC (Routines);
  852.     WriteS (f, "void Begin"); WI (TrafoName); WriteS (f, " ()"); WriteNl (f);
  853.     WriteS (f, "{"); WriteNl (f);
  854.     WriteLine (Codes^.Codes.BeginLine);
  855.     WriteText (f, Codes^.Codes.Begin);
  856.     WriteS (f, "}"); WriteNl (f);
  857.     WriteNl (f);
  858.     WriteS (f, "void Close"); WI (TrafoName); WriteS (f, " ()"); WriteNl (f);
  859.     WriteS (f, "{"); WriteNl (f);
  860.     WriteLine (Codes^.Codes.CloseLine);
  861.     WriteText (f, Codes^.Codes.Close);
  862.     WriteS (f, "}"); WriteNl (f);
  863. ;
  864.       RETURN;
  865.      END;
  866.  
  867.   | Tree.Procedure:
  868. (* line 638 "" *)
  869.      WITH t^.Procedure DO
  870. (* line 638 "" *)
  871.       
  872.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  873.     WriteS (f, "void "); WI (Name); WriteNl (f);
  874.     WriteS (f, "# if defined __STDC__ | defined __cplusplus"); WriteNl (f);
  875.     ListCount := 0;
  876.     WriteS (f, "("); ProcHead3 (InForm); ProcHead3 (OutForm); WriteS (f, ")"); WriteNl (f);
  877.     WriteS (f, "# else"); WriteNl (f);
  878.     ListCount := 0;
  879.     WriteS (f, "("); ProcHead1 (InForm); ProcHead1 (OutForm); WriteS (f, ")"); WriteNl (f);
  880.     ProcHead2 (InForm);
  881.     ProcHead2 (OutForm);
  882.     WriteS (f, "# endif"); WriteNl (f);
  883.     WriteS (f, "{"); WriteNl (f);
  884.     WriteLine (LocalLine);
  885.     WriteText (f, Local);
  886.     RoutineKind := kProcedure;
  887.     InFormals := InForm;
  888.     OutFormals := OutForm;
  889.       IF IsElement (ORD ('n'), Options) THEN
  890.     Tg1 (InForm);
  891.       END;
  892.       IF IsElement (ORD ('b'), Options) THEN
  893.     ImplC (Rules);
  894.         IF IsElement (ORD ('f'), Options) THEN
  895.        WriteS (f, ' yyAbort ("'); WI (Name); WriteS (f, '");'); WriteNl (f);
  896.         END;
  897.       ELSE
  898.     TemposDone := FALSE;
  899.     CommonTestElim (Decisions);
  900.         IF IsElement (ORD ('f'), Options) AND NOT NeedsNoFinale (Decisions) THEN
  901.        WriteS (f, ' yyAbort ("'); WI (Name); WriteS (f, '");'); WriteNl (f);
  902.     END;
  903.       END;
  904.     WriteS (f, ";"); WriteNl (f);
  905.     WriteS (f, "}"); WriteNl (f);
  906.     WriteNl (f);
  907.     ImplC (Next);
  908. ;
  909.       RETURN;
  910.      END;
  911.  
  912.   | Tree.Function:
  913. (* line 676 "" *)
  914.      WITH t^.Function DO
  915. (* line 676 "" *)
  916.       
  917.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  918.     DefC (ReturnForm^.Formal.TypeDesc); WriteS (f, " "); WI (Name); WriteNl (f);
  919.     WriteS (f, "# if defined __STDC__ | defined __cplusplus"); WriteNl (f);
  920.     ListCount := 0;
  921.     WriteS (f, "("); ProcHead3 (InForm); ProcHead3 (OutForm); WriteS (f, ")"); WriteNl (f);
  922.     WriteS (f, "# else"); WriteNl (f);
  923.     ListCount := 0;
  924.     WriteS (f, "("); ProcHead1 (InForm); ProcHead1 (OutForm); WriteS (f, ")"); WriteNl (f);
  925.     ProcHead2 (InForm);
  926.     ProcHead2 (OutForm);
  927.     WriteS (f, "# endif"); WriteNl (f);
  928.     WriteS (f, "{"); WriteNl (f);
  929.     WriteLine (LocalLine);
  930.     WriteText (f, Local);
  931.     RoutineKind := kFunction;
  932.     InFormals := InForm;
  933.     OutFormals := OutForm;
  934.     ReturnFormals := ReturnForm;
  935.       IF IsElement (ORD ('b'), Options) THEN
  936.     ImplC (Rules);
  937.     WriteS (f, ' yyAbort ("'); WI (Name); WriteS (f, '");'); WriteNl (f);
  938.       ELSE
  939.     TemposDone := FALSE;
  940.     CommonTestElim (Decisions);
  941.     IF NOT NeedsNoFinale (Decisions) THEN
  942.        WriteS (f, ' yyAbort ("'); WI (Name); WriteS (f, '");'); WriteNl (f);
  943.     END;
  944.       END;
  945.     WriteS (f, "}"); WriteNl (f);
  946.     WriteNl (f);
  947.     ImplC (Next);
  948. ;
  949.       RETURN;
  950.      END;
  951.  
  952.   | Tree.Predicate:
  953. (* line 709 "" *)
  954.      WITH t^.Predicate DO
  955. (* line 709 "" *)
  956.       
  957.     IF NOT IsExtern THEN WriteS (f, "static "); END;
  958.     WriteS (f, "bool "); WI (Name); WriteNl (f);
  959.     WriteS (f, "# if defined __STDC__ | defined __cplusplus"); WriteNl (f);
  960.     ListCount := 0;
  961.     WriteS (f, "("); ProcHead3 (InForm); ProcHead3 (OutForm); WriteS (f, ")"); WriteNl (f);
  962.     WriteS (f, "# else"); WriteNl (f);
  963.     ListCount := 0;
  964.     WriteS (f, "("); ProcHead1 (InForm); ProcHead1 (OutForm); WriteS (f, ")"); WriteNl (f);
  965.     ProcHead2 (InForm);
  966.     ProcHead2 (OutForm);
  967.     WriteS (f, "# endif"); WriteNl (f);
  968.     WriteS (f, "{"); WriteNl (f);
  969.     WriteLine (LocalLine);
  970.     WriteText (f, Local);
  971.     RoutineKind := kPredicate;
  972.     InFormals := InForm;
  973.     OutFormals := OutForm;
  974.       IF IsElement (ORD ('n'), Options) THEN
  975.     Tg1 (InForm);
  976.       END;
  977.       IF IsElement (ORD ('b'), Options) THEN
  978.     ImplC (Rules);
  979.     WriteS (f, "  return false;"); WriteNl (f);
  980.       ELSE
  981.     TemposDone := FALSE;
  982.     CommonTestElim (Decisions);
  983.     IF NOT NeedsNoFinale (Decisions) THEN
  984.        WriteS (f, "  return false;"); WriteNl (f);
  985.     END;
  986.       END;
  987.     WriteS (f, "}"); WriteNl (f);
  988.     WriteNl (f);
  989.     ImplC (Next);
  990. ;
  991.       RETURN;
  992.      END;
  993.  
  994.   | Tree.Rule:
  995. (* line 744 "" *)
  996.      WITH t^.Rule DO
  997. (* line 744 "" *)
  998.       
  999.     WriteLine (Line);
  1000.     IF HasTempos THEN WriteS (f, " {"); WriteNl (f);
  1001.     END;
  1002.     RuleCount := Index;
  1003.     WithCount := 0;
  1004.     Decls := VarDecls;
  1005.     Declare (Patterns);
  1006.     Declare (Exprs);
  1007.     Declare (Statements);
  1008.     Match (Patterns, InFormals);
  1009.     IF Statements^.Kind # Tree.NoStatement THEN
  1010.        WriteS (f, "  {"); WriteNl (f);
  1011.        ImplC (Statements);
  1012.        WriteS (f, "  }"); WriteNl (f);
  1013.     END;
  1014.     IF NOT HasRejectOrFail THEN
  1015.        AssignFormals (Exprs, OutFormals);
  1016.        CASE RoutineKind OF
  1017.        | kProcedure: WriteS (f, "   return;"); WriteNl (f);
  1018.  
  1019.        | kFunction :
  1020.           IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
  1021.          WriteS (f, "  {register "); DefC (ReturnFormals^.Formal.TypeDesc); WriteS (f, " "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1022.          Declare (Expr);
  1023.          AssignTempo (Expr);
  1024.          WriteS (f, "   "); WI (Tempo); WriteS (f, " = "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1025.          MatchExpr (Expr);
  1026.          WriteS (f, "   return "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1027.          WriteS (f, "  }"); WriteNl (f);
  1028.           ELSIF HasTempos THEN
  1029.          WriteS (f, "  {"); WriteNl (f);
  1030.          Declare (Expr);
  1031.          AssignTempo (Expr);
  1032.          MatchExpr (Expr);
  1033.          WriteS (f, "   return "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1034.          WriteS (f, "  }"); WriteNl (f);
  1035.           ELSE
  1036.          WriteS (f, "   return "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1037.           END;
  1038.  
  1039.        | kPredicate: WriteS (f, "   return true;"); WriteNl (f);
  1040.        END;
  1041.     END;
  1042.     IF HasTempos THEN WriteS (f, " }"); WriteNl (f);
  1043.     END;
  1044.     WriteS (f, "yyL"); WN (RuleCount); WriteS (f, ":;"); WriteNl (f);
  1045.     WriteNl (f);
  1046.     ImplC (Next);
  1047. ;
  1048.       RETURN;
  1049.      END;
  1050.  
  1051.   | Tree.ProcCall:
  1052. (* line 794 "" *)
  1053.      WITH t^.ProcCall DO
  1054. (* line 794 "" *)
  1055.       
  1056.     WriteLine (Pos);
  1057.     AssignTempo (Call);
  1058.     WriteS (f, "   "); Expression (Call); WriteS (f, ";"); WriteNl (f);
  1059.     MatchExpr (Call);
  1060.     ImplC (Next);
  1061. ;
  1062.       RETURN;
  1063.      END;
  1064.  
  1065.   | Tree.Condition:
  1066. (* line 801 "" *)
  1067.      WITH t^.Condition DO
  1068. (* line 801 "" *)
  1069.       
  1070.     WriteLine (Pos);
  1071.     AssignTempo (Expr);
  1072.     WriteS (f, '   if (! ('); Expression (Expr); WriteS (f, ')) goto yyL'); WN (RuleCount); WriteS (f, ';'); WriteNl (f);
  1073.     MatchExpr (Expr);
  1074.     IF Next^.Kind # Tree.NoStatement THEN
  1075.        WriteS (f, "  {"); WriteNl (f);
  1076.        ImplC (Next);
  1077.        WriteS (f, "  }"); WriteNl (f);
  1078.     END;
  1079. ;
  1080.       RETURN;
  1081.      END;
  1082.  
  1083.   | Tree.Assignment:
  1084. (* line 812 "" *)
  1085.      WITH t^.Assignment DO
  1086. (* line 812 "" *)
  1087.       
  1088.     WriteLine (Pos);
  1089.     AssignTempo (Adr);
  1090.     AssignTempo (Expr);
  1091.     IF Object # NoTree THEN
  1092.        WriteS (f, "   "); ImplC (Object^.Formal.Path);
  1093.     ELSE
  1094.        WriteS (f, "   "); Expression (Adr);
  1095.     END;
  1096.     WriteS (f, " = "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1097.     MatchExpr (Adr);
  1098.     MatchExpr (Expr);
  1099.     ImplC (Next);
  1100. ;
  1101.       RETURN;
  1102.      END;
  1103.  
  1104.   | Tree.Reject:
  1105. (* line 826 "" *)
  1106.      WITH t^.Reject DO
  1107. (* line 826 "" *)
  1108.       
  1109.     WriteLine (Pos);
  1110.     WriteS (f, "   goto yyL"); WN (RuleCount); WriteS (f, ";"); WriteNl (f);
  1111. ;
  1112.       RETURN;
  1113.      END;
  1114.  
  1115.   | Tree.Fail:
  1116. (* line 830 "" *)
  1117.      WITH t^.Fail DO
  1118. (* line 830 "" *)
  1119.       
  1120.     WriteLine (Pos);
  1121.     WriteS (f, "   return"); IF RoutineKind = kPredicate THEN WriteS (f, " false"); END; WriteS (f, ";"); WriteNl (f);
  1122. ;
  1123.       RETURN;
  1124.      END;
  1125.  
  1126.   | Tree.TargetStmt:
  1127. (* line 834 "" *)
  1128.      WITH t^.TargetStmt DO
  1129. (* line 834 "" *)
  1130.       
  1131.     WriteLine (Pos);
  1132.     ImplC (Stmt); WriteNl (f);
  1133.     ImplC (Next);
  1134. ;
  1135.       RETURN;
  1136.      END;
  1137.  
  1138.   | Tree.Nl:
  1139. (* line 839 "" *)
  1140.      WITH t^.Nl DO
  1141. (* line 839 "" *)
  1142.       
  1143.     WriteLine (Pos);
  1144.     WriteS (f, "   yyWriteNl;"); WriteNl (f);
  1145.     ImplC (Next);
  1146. ;
  1147.       RETURN;
  1148.      END;
  1149.  
  1150.   | Tree.WriteStr:
  1151. (* line 844 "" *)
  1152.      WITH t^.WriteStr DO
  1153. (* line 844 "" *)
  1154.       
  1155.     WriteLine (Pos);
  1156.     WriteS (f, "   yyWrite ("); WriteString (f, String); WriteS (f, ");"); WriteNl (f);
  1157.     ImplC (Next);
  1158. ;
  1159.       RETURN;
  1160.      END;
  1161.  
  1162.   | Tree.Ident:
  1163. (* line 849 "" *)
  1164.     WITH yyTempo.yyR14 DO
  1165.      WITH t^.Ident DO
  1166. (* line 849 "" *)
  1167.       ;
  1168. (* line 849 "" *)
  1169.       
  1170.     Var := IdentifyVar (Decls, Attribute);
  1171.     IF Var # NoTree THEN ImplC (Var^.Formal.Path); ELSE WI (Attribute); END;
  1172.     ImplC (Next);
  1173. ;
  1174.       RETURN;
  1175.      END;
  1176.     END;
  1177.  
  1178.   | Tree.Any:
  1179. (* line 854 "" *)
  1180.      WITH t^.Any DO
  1181. (* line 854 "" *)
  1182.       
  1183.     WriteString (f, Code);
  1184.     ImplC (Next);
  1185. ;
  1186.       RETURN;
  1187.      END;
  1188.  
  1189.   | Tree.Anys:
  1190. (* line 858 "" *)
  1191.      WITH t^.Anys DO
  1192. (* line 858 "" *)
  1193.       
  1194.     ImplC (Layouts);
  1195.     ImplC (Next);
  1196. ;
  1197.       RETURN;
  1198.      END;
  1199.  
  1200.   | Tree.LayoutAny:
  1201. (* line 862 "" *)
  1202.      WITH t^.LayoutAny DO
  1203. (* line 862 "" *)
  1204.       
  1205.     WriteString (f, Code);
  1206.     ImplC (Next);
  1207. ;
  1208.       RETURN;
  1209.      END;
  1210.  
  1211.   | Tree.Designator:
  1212. (* line 866 "" *)
  1213.      WITH t^.Designator DO
  1214. (* line 866 "" *)
  1215.       
  1216.     ImplC (Object^.Formal.Path); WriteS (f, "->"); WI (Type); WriteS (f, "."); WI (Attribute);
  1217.     ImplC (Next);
  1218. ;
  1219.       RETURN;
  1220.      END;
  1221.  
  1222.   | Tree.Field:
  1223. (* line 870 "" *)
  1224.      WITH t^.Field DO
  1225. (* line 870 "" *)
  1226.       
  1227.     ImplC (Next);
  1228.     WriteS (f, "."); WI (Name);
  1229. ;
  1230.       RETURN;
  1231.      END;
  1232.  
  1233.   | Tree.ConsType:
  1234. (* line 874 "" *)
  1235.      WITH t^.ConsType DO
  1236. (* line 874 "" *)
  1237.       
  1238.     ImplC (Next);
  1239.     WriteS (f, "->"); WI (Name);
  1240. ;
  1241.       RETURN;
  1242.      END;
  1243.  
  1244.   | Tree.Var:
  1245. (* line 878 "" *)
  1246.      WITH t^.Var DO
  1247. (* line 878 "" *)
  1248.       
  1249.     IF IsOutput THEN
  1250.        WriteS (f, "(* "); WI (Name); WriteS (f, ")"); 
  1251.     ELSE
  1252.        WI (Name);
  1253.     END;
  1254. ;
  1255.       RETURN;
  1256.      END;
  1257.  
  1258.   | Tree.NodeTypes:
  1259. (* line 885 "" *)
  1260.      WITH t^.NodeTypes DO
  1261. (* line 885 "" *)
  1262.       
  1263.     WriteS (f, "t"); WI (TreeName^.TreeName.Name);
  1264. ;
  1265.       RETURN;
  1266.      END;
  1267.  
  1268.   | Tree.UserType:
  1269. (* line 888 "" *)
  1270.      WITH t^.UserType DO
  1271. (* line 888 "" *)
  1272.       
  1273.     IF NOT IsElement (Type, UserTypes) THEN WriteS (f, "register "); END; WI (Type);
  1274. ;
  1275.       RETURN;
  1276.      END;
  1277.  
  1278.   ELSE END;
  1279.  
  1280.  END ImplC;
  1281.  
  1282. PROCEDURE Declare (t: Tree.tTree);
  1283.  VAR yyTempo: RECORD CASE : INTEGER OF
  1284.  | 2: yyR2: RECORD
  1285.   Var: tTree;
  1286.   END;
  1287.  END; END;
  1288.  BEGIN
  1289.   IF t = Tree.NoTree THEN RETURN; END;
  1290.  
  1291.   CASE t^.Kind OF
  1292.   | Tree.Formal:
  1293. (* line 895 "" *)
  1294.      WITH t^.Formal DO
  1295. (* line 895 "" *)
  1296.       
  1297.     WriteS (f, "  "); DefC (TypeDesc); WriteS (f, " "); WI (Name); WriteS (f, ";"); WriteNl (f);
  1298.     Declare (Next);
  1299. ;
  1300.       RETURN;
  1301.      END;
  1302.  
  1303.   | Tree.Param:
  1304. (* line 899 "" *)
  1305.     WITH yyTempo.yyR2 DO
  1306.      WITH t^.Param DO
  1307. (* line 899 "" *)
  1308.       ;
  1309. (* line 899 "" *)
  1310.       
  1311.     Var := IdentifyVar (Decls, Name);
  1312.     WriteS (f, "  "); DefC (Var^.Formal.TypeDesc); WriteS (f, " "); WI (Name); WriteS (f, ";"); WriteNl (f);
  1313.     Declare (Next);
  1314. ;
  1315.       RETURN;
  1316.      END;
  1317.     END;
  1318.  
  1319.   | Tree.ProcCall:
  1320. (* line 904 "" *)
  1321.      WITH t^.ProcCall DO
  1322. (* line 904 "" *)
  1323.       
  1324.     Declare (Call);
  1325.     Declare (Next);
  1326. ;
  1327.       RETURN;
  1328.      END;
  1329.  
  1330.   | Tree.Condition:
  1331. (* line 908 "" *)
  1332.      WITH t^.Condition DO
  1333. (* line 908 "" *)
  1334.       
  1335.     Declare (Expr);
  1336.     Declare (Next);
  1337. ;
  1338.       RETURN;
  1339.      END;
  1340.  
  1341.   | Tree.Assignment:
  1342. (* line 912 "" *)
  1343.      WITH t^.Assignment DO
  1344. (* line 912 "" *)
  1345.       
  1346.     Declare (Adr);
  1347.     Declare (Expr);
  1348.     Declare (Next);
  1349. ;
  1350.       RETURN;
  1351.      END;
  1352.  
  1353.   | Tree.TargetStmt:
  1354. (* line 917 "" *)
  1355.      WITH t^.TargetStmt DO
  1356. (* line 917 "" *)
  1357.       
  1358.     Declare (Parameters);
  1359.     Declare (Next);
  1360. ;
  1361.       RETURN;
  1362.      END;
  1363.  
  1364.   | Tree.Statement
  1365.   , Tree.Reject
  1366.   , Tree.Fail
  1367.   , Tree.Nl
  1368.   , Tree.WriteStr:
  1369. (* line 921 "" *)
  1370.      WITH t^.Statement DO
  1371. (* line 921 "" *)
  1372.       
  1373.     Declare (Next);
  1374. ;
  1375.       RETURN;
  1376.      END;
  1377.  
  1378.   | Tree.OnePattern:
  1379. (* line 924 "" *)
  1380.      WITH t^.OnePattern DO
  1381. (* line 924 "" *)
  1382.       
  1383.     IF (Pattern^.Pattern.Tempo # NoIdent) AND (Pattern^.Kind # Tree.DontCare1) THEN
  1384.        WriteS (f, "  "); DefC (Pattern^.Pattern.TypeDesc); WriteS (f, " "); WI (Pattern^.Pattern.Tempo); WriteS (f, ";"); WriteNl (f);
  1385.     END;
  1386.     Declare (Pattern);
  1387.     Declare (Next);
  1388. ;
  1389.       RETURN;
  1390.      END;
  1391.  
  1392.   | Tree.OneExpr
  1393.   , Tree.NamedExpr:
  1394. (* line 931 "" *)
  1395.      WITH t^.OneExpr DO
  1396. (* line 931 "" *)
  1397.       
  1398.     Declare (Expr);
  1399.     Declare (Next);
  1400. ;
  1401.       RETURN;
  1402.      END;
  1403.  
  1404.   | Tree.Decompose:
  1405. (* line 935 "" *)
  1406.      WITH t^.Decompose DO
  1407. (* line 935 "" *)
  1408.       
  1409.     Declare (Patterns);
  1410. ;
  1411.       RETURN;
  1412.      END;
  1413.  
  1414.   | Tree.DontCare:
  1415. (* line 938 "" *)
  1416.      WITH t^.DontCare DO
  1417. (* line 938 "" *)
  1418.       
  1419.     Declare (Tempos);
  1420. ;
  1421.       RETURN;
  1422.      END;
  1423.  
  1424.   | Tree.DontCare1:
  1425. (* line 941 "" *)
  1426.      WITH t^.DontCare1 DO
  1427. (* line 941 "" *)
  1428.       
  1429.     IF Tempo # NoIdent THEN
  1430.        WriteS (f, "  "); DefC (TypeDesc); WriteS (f, " "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1431.     END;
  1432. ;
  1433.       RETURN;
  1434.      END;
  1435.  
  1436.   | Tree.Value:
  1437. (* line 946 "" *)
  1438.      WITH t^.Value DO
  1439. (* line 946 "" *)
  1440.       
  1441.     Declare (Expr);
  1442. ;
  1443.       RETURN;
  1444.      END;
  1445.  
  1446.   | Tree.Compose:
  1447. (* line 949 "" *)
  1448.      WITH t^.Compose DO
  1449. (* line 949 "" *)
  1450.       
  1451.     IF Tempo # NoIdent THEN
  1452.        WriteS (f, "  register "); DefC (TypeDesc); WriteS (f, " "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1453.     END;
  1454.     Declare (Exprs);
  1455. ;
  1456.       RETURN;
  1457.      END;
  1458.  
  1459.   | Tree.Call:
  1460. (* line 955 "" *)
  1461.      WITH t^.Call DO
  1462. (* line 955 "" *)
  1463.       
  1464.     Declare (Expr);
  1465.     Declare (Exprs);
  1466.     Declare (Patterns);
  1467. ;
  1468.       RETURN;
  1469.      END;
  1470.  
  1471.   | Tree.Binary:
  1472. (* line 960 "" *)
  1473.      WITH t^.Binary DO
  1474. (* line 960 "" *)
  1475.       
  1476.     Declare (Lop);
  1477.     Declare (Rop);
  1478. ;
  1479.       RETURN;
  1480.      END;
  1481.  
  1482.   | Tree.PreOperator:
  1483. (* line 964 "" *)
  1484.      WITH t^.PreOperator DO
  1485. (* line 966 "" *)
  1486.       
  1487.     Declare (Expr); 
  1488. ;
  1489.       RETURN;
  1490.      END;
  1491.  
  1492.   | Tree.PostOperator:
  1493. (* line 964 "" *)
  1494.      WITH t^.PostOperator DO
  1495. (* line 966 "" *)
  1496.       
  1497.     Declare (Expr); 
  1498. ;
  1499.       RETURN;
  1500.      END;
  1501.  
  1502.   | Tree.Parents:
  1503. (* line 964 "" *)
  1504.      WITH t^.Parents DO
  1505. (* line 966 "" *)
  1506.       
  1507.     Declare (Expr); 
  1508. ;
  1509.       RETURN;
  1510.      END;
  1511.  
  1512.   | Tree.Index:
  1513. (* line 969 "" *)
  1514.      WITH t^.Index DO
  1515. (* line 969 "" *)
  1516.       
  1517.     Declare (Expr);
  1518.     Declare (Exprs);
  1519. ;
  1520.       RETURN;
  1521.      END;
  1522.  
  1523.   ELSE END;
  1524.  
  1525.  END Declare;
  1526.  
  1527. PROCEDURE Tg1 (t: Tree.tTree);
  1528.  VAR yyTempo: RECORD CASE : INTEGER OF
  1529.  END; END;
  1530.  BEGIN
  1531.   IF t = Tree.NoTree THEN RETURN; END;
  1532.   IF (t^.Kind = Tree.Formal) THEN
  1533. (* line 977 "" *)
  1534.      WITH t^.Formal DO
  1535. (* line 977 "" *)
  1536.       
  1537.     TheName := Name;
  1538.     Tg1 (TypeDesc);
  1539.     Tg1 (Next);
  1540. ;
  1541.       RETURN;
  1542.      END;
  1543.  
  1544.   END;
  1545.   IF (t^.Kind = Tree.NodeTypes) THEN
  1546. (* line 982 "" *)
  1547.      WITH t^.NodeTypes DO
  1548. (* line 982 "" *)
  1549.       
  1550.     WriteS (f, "  if ("); WI (TheName); WriteS (f, " == No"); WI (TreeName^.TreeName.Name);
  1551.     WriteS (f, ") return"); IF RoutineKind = kPredicate THEN WriteS (f, " false"); END; WriteS (f, ";"); WriteNl (f);
  1552. ;
  1553.       RETURN;
  1554.      END;
  1555.  
  1556.   END;
  1557.  END Tg1;
  1558.  
  1559. PROCEDURE CommonTestElim (t: Tree.tTree);
  1560.  VAR yyTempo: RECORD CASE : INTEGER OF
  1561.  END; END;
  1562.  BEGIN
  1563.   IF t = Tree.NoTree THEN RETURN; END;
  1564.  
  1565.   CASE t^.Kind OF
  1566.   | Tree.Decision:
  1567. (* line 990 "" *)
  1568.      WITH t^.Decision DO
  1569. (* line 990 "" *)
  1570.       
  1571.     IF Cases = 0 THEN
  1572.        IF NOT TemposDone AND (OneTest^.Kind = Tree.TestValue) AND NeedsTempo (Then, rule) THEN
  1573.           WriteS (f, " {"); WriteNl (f);
  1574.           TemposDone := TRUE;
  1575.           WITH rule^.Rule DO
  1576.          RuleCount := Index;
  1577.          Decls := VarDecls;
  1578.          Declare (Patterns);
  1579.          Declare (Exprs);
  1580.          Declare (Statements);
  1581.           END;
  1582.           CommonTestElim (OneTest);
  1583.           CommonTestElim (Then);
  1584.           WriteS (f, "  }"); WriteNl (f);
  1585.           WriteS (f, " }"); WriteNl (f);
  1586.        ELSE
  1587.           GetRule (Then, rule);
  1588.           Decls := rule^.Rule.VarDecls;
  1589.           CommonTestElim (OneTest);
  1590.           CommonTestElim (Then);
  1591.           WriteS (f, "  }"); WriteNl (f);
  1592.        END;
  1593.        IF (OneTest^.Kind = Tree.TestValue) AND
  1594.           (OneTest^.TestValue.TypeDesc^.Kind = Tree.UserType) AND
  1595.            IsElement (OneTest^.TestValue.TypeDesc^.UserType.Type, UserTypes) THEN
  1596.           WriteS (f, "  }"); WriteNl (f);
  1597.        END;
  1598.        TemposDone := FALSE;
  1599.        CommonTestElim (Else);
  1600.     ELSE
  1601.        i := Cases; Case (t);
  1602.     END;
  1603. ;
  1604.       RETURN;
  1605.      END;
  1606.  
  1607.   | Tree.Decided:
  1608. (* line 1024 "" *)
  1609.      WITH t^.Decided DO
  1610. (* line 1024 "" *)
  1611.       
  1612.     CommonTestElim (Rule);
  1613.     IF Rule^.Rule.HasExit THEN
  1614.        TemposDone := FALSE;
  1615.        CommonTestElim (Else);
  1616.     END;
  1617. ;
  1618.       RETURN;
  1619.      END;
  1620.  
  1621.   | Tree.TestKind:
  1622. (* line 1031 "" *)
  1623.      WITH t^.TestKind DO
  1624. (* line 1031 "" *)
  1625.       
  1626.     WriteS (f, "  if ("); ImplC (Path); WriteS (f, "->Kind == k"); WI (Name); WriteS (f, ") {"); WriteNl (f);
  1627. ;
  1628.       RETURN;
  1629.      END;
  1630.  
  1631.   | Tree.TestIsType:
  1632. (* line 1034 "" *)
  1633.      WITH t^.TestIsType DO
  1634. (* line 1034 "" *)
  1635.       
  1636.     WriteS (f, "  if ("); WI (TypeDesc^.NodeTypes.TreeName^.TreeName.Name); WriteS (f, "_IsType ("); ImplC (Path);
  1637.        WriteS (f, ", k"); WI (Name); WriteS (f, ")) {"); WriteNl (f);
  1638. ;
  1639.       RETURN;
  1640.      END;
  1641.  
  1642.   | Tree.TestNil:
  1643. (* line 1038 "" *)
  1644.      WITH t^.TestNil DO
  1645. (* line 1038 "" *)
  1646.       
  1647.     WriteS (f, "  if ("); ImplC (Path); WriteS (f, " == NULL) {"); WriteNl (f);
  1648. ;
  1649.       RETURN;
  1650.      END;
  1651.  
  1652.   | Tree.TestNonlin:
  1653. (* line 1041 "" *)
  1654.      WITH t^.TestNonlin DO
  1655. (* line 1041 "" *)
  1656.       
  1657.     WriteS (f, "  if (equal"); DefC (TypeDesc); WriteS (f, " ("); ImplC (Path); WriteS (f, ", "); ImplC (Path2); WriteS (f, ")) {"); WriteNl (f);
  1658. ;
  1659.       RETURN;
  1660.      END;
  1661.  
  1662.   | Tree.TestValue:
  1663.   IF (t^.TestValue.TypeDesc^.Kind = Tree.UserType) THEN
  1664. (* line 1044 "" *)
  1665.    LOOP
  1666.      WITH t^.TestValue DO
  1667. (* line 1045 "" *)
  1668.       IF NOT ((IsElement (t^.TestValue.TypeDesc^.UserType.Type, UserTypes))) THEN EXIT; END;
  1669. (* line 1046 "" *)
  1670.       
  1671.     AssignTempo (Expr);
  1672.     WriteS (f, "  {"); DefC (TypeDesc); WriteS (f, " yyT; yyT = "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1673.     MatchExpr (Expr);
  1674.     WriteS (f, "  if (equal"); DefC (TypeDesc); WriteS (f, " ("); ImplC (Path); WriteS (f, ", yyT)) {"); WriteNl (f);
  1675. ;
  1676.       RETURN;
  1677.      END;
  1678.    END;
  1679.  
  1680.   END;
  1681. (* line 1052 "" *)
  1682.      WITH t^.TestValue DO
  1683. (* line 1052 "" *)
  1684.       
  1685.     AssignTempo (Expr);
  1686.     WriteS (f, "  if (equal"); DefC (TypeDesc); WriteS (f, " ("); ImplC (Path); WriteS (f, ", "); Expression (Expr); WriteS (f, ")) {"); WriteNl (f);
  1687.     MatchExpr (Expr);
  1688. ;
  1689.       RETURN;
  1690.      END;
  1691.  
  1692.   | Tree.Rule:
  1693. (* line 1057 "" *)
  1694.      WITH t^.Rule DO
  1695. (* line 1057 "" *)
  1696.       
  1697.     WriteLine (Line);
  1698.     RuleCount := Index;
  1699.     WithCount := 0;
  1700.     Decls := VarDecls;
  1701.     IF HasTempos AND NOT TemposDone THEN WriteS (f, " {"); WriteNl (f);
  1702.        Declare (Patterns);
  1703.        Declare (Exprs);
  1704.        Declare (Statements);
  1705.     END;
  1706.     IF Statements^.Kind # Tree.NoStatement THEN
  1707.        WriteS (f, "  {"); WriteNl (f);
  1708.        ImplC (Statements);
  1709.        WriteS (f, "  }"); WriteNl (f);
  1710.     END;
  1711.     IF NOT HasRejectOrFail THEN
  1712.        AssignFormals (Exprs, OutFormals);
  1713.        CASE RoutineKind OF
  1714.        | kProcedure: WriteS (f, "   return;"); WriteNl (f);
  1715.  
  1716.        | kFunction :
  1717.           IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
  1718.          WriteS (f, "  {register "); DefC (ReturnFormals^.Formal.TypeDesc); WriteS (f, " "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1719.          Declare (Expr);
  1720.          AssignTempo (Expr);
  1721.          WriteS (f, "   "); WI (Tempo); WriteS (f, " = "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1722.          MatchExpr (Expr);
  1723.          WriteS (f, "   return "); WI (Tempo); WriteS (f, ";"); WriteNl (f);
  1724.          WriteS (f, "  }"); WriteNl (f);
  1725.           ELSIF HasTempos THEN
  1726.          WriteS (f, "  {"); WriteNl (f);
  1727.          Declare (Expr);
  1728.          AssignTempo (Expr);
  1729.          MatchExpr (Expr);
  1730.          WriteS (f, "   return "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1731.          WriteS (f, "  }"); WriteNl (f);
  1732.           ELSE
  1733.          WriteS (f, "   return "); Expression (Expr); WriteS (f, ";"); WriteNl (f);
  1734.           END;
  1735.  
  1736.        | kPredicate: WriteS (f, "   return true;"); WriteNl (f);
  1737.        END;
  1738.     END;
  1739.     IF HasTempos AND NOT TemposDone THEN WriteS (f, " }"); WriteNl (f);
  1740.     END;
  1741.     IF HasExit OR NeedsMatch (Tests) THEN WriteS (f, "yyL"); WN (RuleCount); WriteS (f, ":;"); WriteNl (f);
  1742.     END;
  1743.     WriteNl (f);
  1744. ;
  1745.       RETURN;
  1746.      END;
  1747.  
  1748.   ELSE END;
  1749.  
  1750.  END CommonTestElim;
  1751.  
  1752. PROCEDURE Case (t: Tree.tTree);
  1753.  VAR yyTempo: RECORD CASE : INTEGER OF
  1754.  | 1: yyR1: RECORD
  1755.   n: CARDINAL;
  1756.   END;
  1757.  END; END;
  1758.  BEGIN
  1759.   IF t = Tree.NoTree THEN RETURN; END;
  1760.   IF (t^.Kind = Tree.Decision) THEN
  1761. (* line 1110 "" *)
  1762.     WITH yyTempo.yyR1 DO
  1763.      WITH t^.Decision DO
  1764. (* line 1110 "" *)
  1765.       ;
  1766. (* line 1110 "" *)
  1767.       
  1768.     WriteNl (f);
  1769.     WriteS (f, "  switch ("); ImplC (OneTest^.OneTest.Path); WriteS (f, "->Kind) {"); WriteNl (f);
  1770.     n := i;
  1771.     WHILE n > 0 DO
  1772.        IF NOT IsEmpty (t^.Decision.OneTest^.TestIsType.TypeDesc^.NodeTypes.Types) THEN
  1773.           Case (t^.Decision.OneTest);
  1774.           CommonTestElim (t^.Decision.Then);
  1775.           IF NOT NeedsNoFinale (t^.Decision.Then) THEN
  1776.          WriteS (f, "  break;"); WriteNl (f);
  1777.           END;
  1778.        END;
  1779.        t := t^.Decision.Else;
  1780.        DEC (n);
  1781.     END;
  1782.     WriteS (f, "  }"); WriteNl (f);
  1783.     WriteNl (f);
  1784.     CommonTestElim (t);
  1785. ;
  1786.       RETURN;
  1787.      END;
  1788.     END;
  1789.  
  1790.   END;
  1791.   IF (t^.Kind = Tree.TestKind) THEN
  1792. (* line 1129 "" *)
  1793.      WITH t^.TestKind DO
  1794. (* line 1129 "" *)
  1795.       
  1796.     WriteS (f, "  case k"); WI (Name); WriteS (f, ":"); WriteNl (f);
  1797. ;
  1798.       RETURN;
  1799.      END;
  1800.  
  1801.   END;
  1802.   IF (t^.Kind = Tree.TestIsType) THEN
  1803. (* line 1132 "" *)
  1804.      WITH t^.TestIsType DO
  1805. (* line 1132 "" *)
  1806.       
  1807.     Case (TypeDesc);
  1808. ;
  1809.       RETURN;
  1810.      END;
  1811.  
  1812.   END;
  1813.   IF (t^.Kind = Tree.NodeTypes) THEN
  1814. (* line 1135 "" *)
  1815.      WITH t^.NodeTypes DO
  1816. (* line 1135 "" *)
  1817.       
  1818.     FOR j := Minimum (Types) TO Maximum (Types) DO
  1819.        IF IsElement (j, Types) THEN
  1820.           TheClass := LookupClass (TreeName^.TreeName.Classes, j);
  1821.           WriteS (f, "  case k"); WI (TheClass^.Class.Name); WriteS (f, ":"); WriteNl (f);
  1822.        END;
  1823.     END;
  1824. ;
  1825.       RETURN;
  1826.      END;
  1827.  
  1828.   END;
  1829.  END Case;
  1830.  
  1831. PROCEDURE BeginC;
  1832.  BEGIN
  1833.  END BeginC;
  1834.  
  1835. PROCEDURE CloseC;
  1836.  BEGIN
  1837.  END CloseC;
  1838.  
  1839. PROCEDURE yyExit;
  1840.  BEGIN
  1841.   IO.CloseIO; System.Exit (1);
  1842.  END yyExit;
  1843.  
  1844. BEGIN
  1845.  yyf    := IO.StdOutput;
  1846.  Exit    := yyExit;
  1847.  BeginC;
  1848. END C.
  1849.